package com.sh.data.engine.repository.dao.integration.offline.entity;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.sh.data.engine.repository.dao.base.EngineBaseModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Tolerate;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;
import java.util.List;

/**
 * @author: mengzheng.mhc
 * @date: 2024/6/18 11:08
 */
@Data
@Builder(toBuilder = true)
@EqualsAndHashCode(callSuper = true)
@TableName(value = "tb_offline_sync", autoResultMap = true)
@AllArgsConstructor
public class OfflineSyncEntity extends EngineBaseModel<OfflineSyncEntity> {

    private Long xxlJobId;

    private Long projectId;

    /**
     * 所在目录id
     */
    private Long dirId;

    /**
     * 任务名称
     */
    private String taskName;

    /**
     * 任务描述
     */
    private String remark;

    /**
     * 任务类型
     */
    private Integer taskType;

    /**
     * 如果是文件同步，那么需要穿入文件地址
     */
    private String filePath;

    /**
     * 来源数据源类型
     */
    private String sourceDsType;

    /**
     * 来源数据源id
     */
    private Long sourceDsId;

    /**
     * 目标数据源类型
     */
    private String targetDsType;

    /**
     * 目标数据源id
     */
    private Long targetDsId;

    /**
     * ods层级系统
     */
    private String odsName;

    /**
     * 表的增量类型 f-全量 i-增量
     */
    private String tableIncType;

    /**
     * 表的刷新频率
     */
    private String tableFrequency;

    /**
     * 是否有分区 0-否 1-有
     */
    private Integer isParition;

    /**
     * 是否是富文本 0-否 1-有
     */
    private Integer isSupportText;

    private Integer openSchedule;

    /**
     * 分区定义 json
     */
    @TableField(typeHandler = FastjsonTypeHandler.class)
    private List<PartitionField> paritions;

    private String sourceTable;

    private String targetTable;

    @TableField(exist = false)
    private List<FieldMapping> fieldMappings;

    public List<FieldMapping> getFieldMappings() {
        return JSONArray.parseArray(fieldMapping, FieldMapping.class);
    }

    private String fieldMapping;

    public void setFieldMapping() {
        this.fieldMapping = JSONArray.toJSONString(fieldMappings);
    }

    /**
     * 替换规则 1-写入前清理已有数据 Insert Overwrite 2-写入前保留已有数据 Insert Into 3-同名覆盖 4-同名忽略 5-主键冲突，替换原有数据
     * 6-主键冲突，丢弃新数据 7-key值相同，覆盖 8-key值相同，忽略
     */
    private Integer dataReplaceRuleId;

    /*同步前是否清理 1-是 0-否"*/
    private Integer isTruncate;

    /**
     * 失败记录数超过多少时，任务结束,值为-1时表示不限制
     */
    private Integer errorNumLimit;

    /**
     * 过滤条件
     */
    private String incFilter;

    private Integer pgText;

    private Date publishTime;

    /*周期调度*/
    @TableField(typeHandler = FastjsonTypeHandler.class)
    private OfflineSyncSchedule schedule;

    /**
     * 是否发布状态
     *
     * @see com.sh.data.engine.domain.integration.model.enums.OfflineSyncTaskStatus
     */
    private Integer taskStatus;

    /**
     * 运行状态(默认是unrunning 3)
     *
     * @see com.sh.data.engine.domain.integration.model.enums.OfflineSyncTaskStatus
     */
    @Builder.Default
    private Integer taskRunStatus = 3;

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date startTime;

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date endTime;

    /**
     * 每次读取数据条数
     */
    private Integer fetchSize;

    /**
     * 每次写入数据条数
     */
    private Integer batchSize;

    /**
     * 并发数
     */
    private Integer channel;

    /**
     * 分片字段
     */
    private String splitKey;

    private Date planTime;

    @Data
    @Builder(toBuilder = true)
    public static class FieldMapping {

        /*来源字段名*/
        private String sourceField;

        /*来源字段类型*/
        private String sourceFieldType;

        /*来源字段是否是主键*/
        private Integer isSourceFieldPk;

        /*目标字段名*/
        private String targetField;

        /*目标字段类型*/
        private String targetFieldType;

        /*目标字段是否是主键*/
        private Integer isTargetFieldPk;

        /*目标字段长度*/
        private Integer targetColumnSize;

        /*目标字段小数位长度*/
        private Integer targetDecimalDigits;

        /*目标字段备注*/
        private String targetComment;

        /*日期编码格式*/
        private String dateFormat;

        @Tolerate
        public FieldMapping() {
        }
    }

    @Data
    @Builder(toBuilder = true)
    public static class PartitionField {

        /*分区名名称*/
        private String fieldName;

        /*分区值*/
        private String fieldValue;

        @Tolerate
        public PartitionField() {
        }
    }

    @Data
    @Builder(toBuilder = true)
    public static class OfflineSyncSchedule {

        /*调度状态 0-未冻结 1-冻结"*/
        private Integer status;

        /*生效开始时间*/
        private Date effectiveDateStart;

        /*生效结束时间*/
        private Date effectiveDateEnd;

        /*调度周期 0-月 1-周 2-天 3-小时 4-分钟*/
        private Integer cycle;

        /*执行开始时间的小时*/
        private String startTimeHour;

        /*执行开始时间的分钟*/
        private String startTimeMin;

        /*执行结束时间的小时*/
        private String endTimeHour;

        /*执行结束时间的分钟*/
        private String endTimeMin;

        /*
          月、周为执行日期 ，小时、分钟为执行间隔
        */
        private String execPoint;

        /*跨周期依赖 0-不依赖上一周期 1-等待上一周期结束*/
        private Integer cycleDependence;

        @Tolerate
        public OfflineSyncSchedule() {
        }
    }

    @Tolerate
    public OfflineSyncEntity() {
    }

//    /**
//     * 待发布
//     *
//     * @return isToRelease
//     */
//    public Boolean isToRelease() {
//        return OfflineSyncTaskStatus.torelease.getTaskStatus().equals(this.taskStatus);
//    }
//
//    /**
//     * 成功
//     *
//     * @return isSuccess
//     */
//    public Boolean isSuccess() {
//        return OfflineSyncTaskStatus.success.getTaskStatus().equals(this.taskRunStatus);
//    }
//
//    /**
//     * 失败
//     *
//     * @return isFail
//     */
//    public Boolean isFail() {
//        return OfflineSyncTaskStatus.failure.getTaskStatus().equals(this.taskRunStatus);
//    }
//
//    /**
//     * 运行中
//     *
//     * @return running
//     */
//    public Boolean isRunning() {
//        return OfflineSyncTaskStatus.running.getTaskStatus().equals(this.taskRunStatus);
//    }
}
